﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Data.Objects.DataClasses;
using System.Data.Objects;
using System.Data.Metadata.Edm;

namespace MShop.Core.Domain
{
    public static  class EntityObjectExtensions 
    {
        

        public static ObjectContext GetContext(this IEntityWithRelationships entity)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");

            var relationshipManager = entity.RelationshipManager;

            

            var relatedEnd = relationshipManager.GetAllRelatedEnds()
                                                .FirstOrDefault();

            if (relatedEnd == null)
                throw new Exception("No relationships found");

            var query = relatedEnd.CreateSourceQuery() as ObjectQuery;

            if (query == null)
                throw new Exception("The Entity is Detached");

            return query.Context;
        }


        public static EntityType GetCSpaceEntityType<T>(this MetadataWorkspace workspace)
        {
            if (workspace == null)
                throw new ArgumentNullException("workspace");
            // Make sure the assembly for "T" is loaded 
            workspace.LoadFromAssembly(typeof(T).Assembly);
            // Try to get the ospace type and if that is found 
            // look for the cspace type too. 
            EntityType ospaceEntityType = null;
            StructuralType cspaceEntityType = null;
            if (workspace.TryGetItem<EntityType>(
                typeof(T).FullName,
                DataSpace.OSpace,
                out ospaceEntityType))
            {
                if (workspace.TryGetEdmSpaceType(
                    ospaceEntityType,
                    out cspaceEntityType))
                {
                    return cspaceEntityType as EntityType;
                }
            }
            return null;
        }

        public static T Get<T, K>(this ObjectQuery<T> query, K key)
        {
            //Get the EntityType             
            EntityType entityType = query.Context.MetadataWorkspace                                          
                                         .GetCSpaceEntityType<T>();

            if (entityType.KeyMembers.Count != 1)
                throw new Exception("You need to pass all the keys");

            //Build the ESQL 
            string eSQL = string.Format("it.{0} = @{0}",
                                        entityType.KeyMembers[0].Name);

            //Execute the query 
            return query.Where(
                eSQL,
                new ObjectParameter(entityType.KeyMembers[0].Name, key)
            ).First();
        }
    }
}